/*
 * pkg_parser.h
 *
 *  Created on: 2021年1月27日
 *      Author: kimfeng
 */

#ifndef PKG_PARSER_H_
#define PKG_PARSER_H_

#include "asock_type.h"

#include <vector>
#include <boost/logic/tribool.hpp>
#include <boost/tuple/tuple.hpp>

class pkg_parser
{
public:
	explicit pkg_parser() { m_state = eStart; }

	template<typename InputIterator>
	boost::tuple<boost::tribool, InputIterator> parse(sck_pkg_t& pkg, vec_data_t& data,
			InputIterator begin, InputIterator end, size_t& bytes_parsed)
	{
		InputIterator orig_begin = begin;
		while (begin != end)
		{
			boost::tribool result = consume(pkg, data, *begin++);
			if (result || !result)
			{
				bytes_parsed += begin - orig_begin;
				return boost::make_tuple(result, begin);
			}
		}
		bytes_parsed += begin - orig_begin;
		boost::tribool result = boost::indeterminate;
		return boost::make_tuple(result, begin);
	}
	bool is_start_state() { return eStart == m_state; }

private:
	/// Handle the next character of input.
	boost::tribool consume(sck_pkg_t& pkg, vec_data_t& payload_buffer, uchar input);
	enum state
	{
		eStart = 0,
		eMagic1,
		eMagic2,
		eVer1,
		eVer2,
		eReq1,
		eReq2,
		eSeq1,
		eSeq2,
		eType1,
		eType2,
		ePend1,
		ePend2,
		eLen1,
		eLen2,
		eLen3,
		eLen4,
		eReadPayLoad,
	} m_state;

	vec_data_t m_hdr_buffer;
};

#endif /* PKG_PARSER_H_ */
